#include "bsp_usart.h"

int debug_uart_config(void)
{

#if defined(__GNUC__)
    setvbuf(stdout, NULL, _IONBF, 0);
#endif
    DEBUG_USART_CLK_ENABLE();

    /* USART Init */
    LL_USART_SetBaudRate(DEBUG_USART, SystemCoreClock, LL_USART_OVERSAMPLING_16, DEBUG_USART_BAUDRATE);
    LL_USART_SetDataWidth(DEBUG_USART, LL_USART_DATAWIDTH_8B);
    LL_USART_SetStopBitsLength(DEBUG_USART, LL_USART_STOPBITS_1);
    LL_USART_SetParity(DEBUG_USART, LL_USART_PARITY_NONE);
    LL_USART_SetHWFlowCtrl(DEBUG_USART, LL_USART_HWCONTROL_NONE);
    LL_USART_SetTransferDirection(DEBUG_USART, LL_USART_DIRECTION_TX_RX);
    LL_USART_Enable(DEBUG_USART);
    LL_USART_ClearFlag_TC(DEBUG_USART);

    DEBUG_USART_RX_GPIO_CLK_ENABLE();
    DEBUG_USART_TX_GPIO_CLK_ENABLE();
    
    LL_GPIO_SetPinMode(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, LL_GPIO_MODE_ALTERNATE);
    LL_GPIO_SetPinSpeed(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, LL_GPIO_SPEED_FREQ_VERY_HIGH);
    LL_GPIO_SetPinPull(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, LL_GPIO_PULL_UP);
    LL_GPIO_SetAFPin_8_15(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, DEBUG_USART_TX_AF);

    LL_GPIO_SetPinMode(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, LL_GPIO_MODE_ALTERNATE);
    LL_GPIO_SetPinSpeed(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, LL_GPIO_SPEED_FREQ_VERY_HIGH);
    LL_GPIO_SetPinPull(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, LL_GPIO_PULL_UP);
    LL_GPIO_SetAFPin_8_15(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, DEBUG_USART_RX_AF);
    return 0;
}
INIT_BOARD_EXPORT(debug_uart_config);

#ifdef RT_USING_CONSOLE

void rt_hw_console_output(const char *str)
{
    rt_enter_critical();
    while (*str != '\0')
    {
        if (*str == '\n')
        {
            LL_USART_TransmitData8(DEBUG_USART, '\r');
            while (SET != LL_USART_IsActiveFlag_TXE(DEBUG_USART))
                ;
        }
        LL_USART_TransmitData8(DEBUG_USART, *str++);
        while (SET != LL_USART_IsActiveFlag_TXE(DEBUG_USART))
            ;
    }
    rt_exit_critical();
}
#endif

#ifdef RT_USING_FINSH
char rt_hw_console_getchar(void)
{
    /* Note: the initial value of ch must < 0 */
    int ch = -1;

    if (RESET != LL_USART_IsActiveFlag_RXNE(DEBUG_USART))
    {
        ch = (uint8_t)LL_USART_ReceiveData8(DEBUG_USART);
    }
    else
    {
        if (RESET != LL_USART_IsActiveFlag_ORE(DEBUG_USART))
        {
            LL_USART_ClearFlag_TC(DEBUG_USART);
        }
        rt_thread_mdelay(10);
    }
    return ch;
}
#endif
